import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.ConcurrentLinkedQueue;

/**
 * picks up URL objects from the queue, retrieves the page and stuffs 
 * it into a page (string) buffer (take care on size of content being buffered).
 */
public class PageRetriever implements Runnable {
	// INSTANCE FIELDS **********************************************
	/**
	 * Buffer of pages retrieved and yet to be parsed.
	 */
	private PageBuffer pbuff;
	
	/**
	 * Buffer of urls of pages yet to be retrieved.
	 */
	private PageToRetrieve rbuff;
	
	/**
	 * Page being retrieved.
	 */
	private String current;
	
	/**
	 * Queue underlying the PageBuffer.
	 */
	private ConcurrentLinkedQueue<Pair<String, String>> pqueue;
	
	/**
	 * Queue underlying the PageToRetrieve buffer.
	 */
	private ConcurrentLinkedQueue<String> rqueue;
	
	
	// CONSTRUCTORS *************************************************
	/**
	 * Empty constructor.
	 */
	private PageRetriever() {}
	
	/**
	 * Creates a PageRetriever with references to a queue with urls to retrieve pages from,
	 * and a queue to store the retrieved pages.
	 * @param pagebuff
	 * @param retbuff
	 */
	public PageRetriever(PageBuffer pagebuff, PageToRetrieve retbuff) {
		this();
		pbuff = pagebuff;
		rbuff = retbuff;
		pqueue = pbuff.queue();
		rqueue = rbuff.queue();
		current = "";
	}
	
	// METHODS ******************************************************
    /**
     * Get the next link in the url queue and store the page it points to in the page queue.
     */
    public void tick() {     
    	if (rbuff.hasNext()) {
		    current = rqueue.poll();
			String getHtml = getHtml(current);
			if (!getHtml.equals("")) {
				pqueue.add(new Pair<String, String>(current, getHtml(current)));
				rbuff.incrementPageCount(); 
			}
    	}
    }
    
	
	/**
	 * Retrieves the page pointed to by url.
	 * @param Url of the page to retrieve
	 * @return String containing the page's html
	 */
	private String getHtml(String url) {
		URL u = null;
		String ret = "";
		try {
			u = new URL(url);
			InputStream in = u.openStream();
			BufferedReader buff = new BufferedReader(new InputStreamReader(in));
			StringBuilder sb = new StringBuilder();
			boolean cont = false;
			String next;
			while ((next = buff.readLine()) != null) {
				sb.append(next);
				sb.append("\n");
			} while(cont);
			ret = sb.toString();
		} catch (MalformedURLException mf) {
			System.out.println("Encountered malformed URL! URL was: " +url);
			ret = "";
		} catch (IOException io) {
			System.out.println("Could not get input stream from URL: " +url);
			ret = "";
		}
		return ret;
	}

	@Override
	public void run() {
		tick();		
	}
}
